package com.xiong.multipleExcel;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.fastjson.JSON;
import com.xiong.multipleExcel.constant.SystemConstants;
import com.xiong.multipleExcel.pojo.PriceSource;
import com.xiong.multipleExcel.pojo.PriceTarget;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


@Slf4j
@SpringBootTest(classes = ExcelTest.class)
class ExcelTest {

    //读取输出数据
    public ArrayList<PriceTarget> targetRead() {
        AtomicInteger i = new AtomicInteger(1);

        ArrayList<PriceTarget> priceTargets = new ArrayList<>();
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        // 这里每次会读取100条数据 然后返回过来 直接调用使用数据就行
        EasyExcel.read(SystemConstants.PRICE_TARGET, PriceTarget.class, new PageReadListener<PriceTarget>(priceTargetList -> {
            for (PriceTarget priceTarget : priceTargetList) {
                log.info("读取到第 {} 数据{}", i.getAndIncrement(), JSON.toJSONString(priceTarget));
            }
            priceTargets.addAll(priceTargetList);
        })).sheet().doRead();
        log.info("目标数据共读取 {} 条",priceTargets.size());
        System.out.println(priceTargets.toString());

        System.out.println("===================================读取完成===============================================");

        return priceTargets;
    }

    /**
     * 读取需要填充的价格数量
     * @return java.util.List<com.xiong.excel.pojo.PriceSource>
     * @author 熊林飞
     * @date: 2022/8/22 15:15
     */
    public List<PriceSource> sourceRead() {
        AtomicInteger i = new AtomicInteger(1);

        ArrayList<PriceSource> priceSources = new ArrayList<>();
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        // 这里每次会读取100条数据 然后返回过来 直接调用使用数据就行
        EasyExcel.read(SystemConstants.PRICE_SOURCE, PriceSource.class, new PageReadListener<PriceSource>(priceSourceList -> {
            for (PriceSource priceSource : priceSourceList) {
                log.info("读取到第 {} 数据{}", i.getAndIncrement(), JSON.toJSONString(priceSource));
            }
            priceSources.addAll(priceSourceList);
        })).sheet("Sheet1").doRead();
        log.info("资源数据共读取 {} 条",priceSources.size());
        System.out.println(priceSources.toString());

        System.out.println("===================================读取完成===============================================");

        return priceSources;
    }

    /**
     * 最后写出需要的数据
     * @author 熊林飞
     * @date: 2022/8/22 14:55
     */
    @Test
    public void finalWriteOut() {

        //读取报价资源表
        List<PriceSource> priceSources = this.sourceRead();
        // 读取导出填充数据表
        List<PriceTarget> priceTargets = this.targetRead();
        int priceTargetCount = priceSources.size();

        //过滤相同的 选出辅助数量最大的
        System.out.println("===================================开始过滤去重===============================================");
        // x计算去重是多少行 需要从2开始,因为数组从0开始计数, 表格第一行为2
        int x = 2;
        //
        List<Integer> filterNub = new ArrayList<>();
        for (int i = 0; i < priceTargets.size(); i++) {
            for (int j = i+1; j < priceTargets.size(); j++) {
                PriceTarget a = priceTargets.get(i);
                PriceTarget b = priceTargets.get(j);
                //
//                System.out.println(i+"===="+j);
//                System.out.println(a);
//                System.out.println(b);
                if ((a.getMatterName() + a.getLongDesc() + a.getOrderRemark())
                        .equals(b.getMatterName() + b.getLongDesc() + b.getOrderRemark())){
                    if(a.getAssistAmount() >= b.getAssistAmount()){
                        log.info("成功过滤一条数据 第 {} 行 ==={}",j+x,b);
                        filterNub.add(j+x);
                        x++;
                        priceTargets.remove(j);
                        j--;
//                        priceTargets.set(j,null);
                    }else {
                        log.info("成功过滤一条数据 第 {} 行 ==={}",i+x,a);
                        filterNub.add(i+x);
                        x++;
//                        priceTargets.set(i,null);
                        priceTargets.remove(i);
                        i--;
                        break;
                    }
                }
            }
        }
//        for (int i = 0; i < priceTargets.size(); i++) {
//            if(priceTargets.get(i) == null){
//                priceTargets.remove(i);
//            }
//        }
        log.info("过滤完成剩余 {} 条数据",priceTargets.size());

        //进行价格和数量填充
        System.out.println("===================================进行价格和数量填充===============================================");
        int c = 1;
        int b = 1;
        //多匹配的数量
        int errNub = 0;
        //多那些source是匹配的
        List<Integer> muchMatchCode = new ArrayList<>();
        //未匹配
        List<Integer> noMatchCode = new ArrayList<>();
        for (PriceSource source : priceSources) {
            log.info("第 {} 条数据开始匹配=={}",b++,source);

            String sourceStr = source.getMatterName() + source.getLongDesc() + source.getOrderRemark();
            sourceStr = sourceStr.replaceAll("&nbsp;"," ");
            sourceStr = sourceStr.replaceAll("&lt;","<");
            for (PriceTarget target : priceTargets) {
                if ((target.getMatterName() + target.getLongDesc() + target.getOrderRemark())
                        .equals(sourceStr)){
                    target.setNeedAmount(source.getAmount());
                    target.setNoPriceSingle(source.getNoPriceSingle());

                    log.info("填充已完成第 {} 条数据=={}",c++,target);
//                    break;
                }
            }
            if(b == (c+1)){
                log.error("填充异常!!!! 第 {} 条数据未匹配成功=={}",b-1,source);
                noMatchCode.add(b-1);
                c = b;
            }
            if(b < c){
                log.error("填充异常!!!! 第 {} 条数据在第 {} 行左右填充多次=={}",b,c,source);
                errNub = errNub + (c - b);
                muchMatchCode.add(b-1);
                c = b;
            }
        }

        // 进行导出  这里 会填充到第一个sheet， 然后文件流会自动关闭
        String fileName = SystemConstants.TARGET_FILE_NAME + "报价单导出" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("MM-dd日HH-mm-ss")) + ".xlsx";
        EasyExcel.write(fileName).withTemplate(SystemConstants.PRICE_TARGET_Template).sheet().doFill(priceTargets);

        System.out.println("===================================导出成功===============================================");
        log.info("被填充数据共: {} 条, 过滤去重后剩余: {} 条, 被过滤分别是第 {} 条",priceTargetCount,priceTargets.size(),filterNub.toString());
        log.info("需填充数据: {} 条",priceSources.size());
        log.info("实际填充了: {} 条",b-1-noMatchCode.size()+errNub);
        log.info("未匹配数据: {} 条, 分别是第 {} 条",noMatchCode.size(),noMatchCode.toString());
        log.info("重复匹配数据: {} 条, 分别是第 {} 条",errNub,muchMatchCode.toString());
    }

















//    /**
//     * 根据模板写入
//     * <p>1. 创建excel对应的实体对象 参照{@link IndexData}
//     * <p>2. 使用{@link ExcelProperty}注解指定写入的列
//     * <p>3. 使用withTemplate 写取模板
//     * <p>4. 直接写即可
//     */
//    @Test
//    public void templateWrite() {
//        String templateFileName = SystemConstants.PRICE_TARGET;
//        String fileName = "D:\\360极速浏览器\\javaWeb\\target\\" + "templateWrite" + System.currentTimeMillis() + ".xlsx";
//        // 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭
//
//        ArrayList<PriceSource> priceSources = new ArrayList<>();
//        priceSources.add(new PriceSource().setNeedAmount("1").setNoPrice("22"));
//        priceSources.add(new PriceSource().setNeedAmount("2").setNoPrice("33"));
//        priceSources.add(new PriceSource().setNeedAmount("3").setNoPrice("44"));
//        EasyExcel.write(fileName, DemoData.class).withTemplate(templateFileName).sheet().doWrite(priceSources);
//    }

}
